<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta http-equiv="cache-control" content="no-cache">
<title>Genivia - The iOS Plugin</title>
<link href="genivia_tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="genivia_content.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="top">
 <div id="titlearea">
  <table height="72px" width="100%" cellspacing="0" cellpadding="0">
   <tbody>
    <tr>
     <td width="10%">&nbsp;</td>
     <td width="175px"><a href="https://www.genivia.com"><img alt="Genivia" src="GeniviaLogo2_trans_noslogan.png"/></a></td>
     <td class="tab_home"><a href="https://www.genivia.com">Home</a></td>
     <td class="tab_home"><a href="https://www.genivia.com/docs.html">Documentation</a></td>
     <td>
      <div style="float: right; font-size: 18px; font-weight: bold;">The iOS Plugin</div>
      <br>
      <div style="float: right; font-size: 10px;">updated Wed Apr 8 2020 by Robert van Engelen</div>
     </td>
     <td width="10%">&nbsp;</td>
    </tr>
   </tbody>
  </table>
 </div>
<!-- Generated by Doxygen 1.8.11 -->
  <div id="navrow1" class="tabs">
    <ul class="tablist">
      <li class="current"><a href="index.html"><span>Main&#160;Page</span></a></li>
      <li><a href="pages.html"><span>Related&#160;Pages</span></a></li>
      <li><a href="annotated.html"><span>Classes</span></a></li>
      <li><a href="files.html"><span>Files</span></a></li>
    </ul>
  </div>
</div><!-- top -->
<div class="header">
  <div class="headertitle">
<div class="title">The iOS Plugin </div>  </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#title">The iOS Plugin</a></li>
<li class="level1"><a href="#ios_overview">Overview</a></li>
<li class="level1"><a href="#ios_start">Getting Started</a></li>
<li class="level1"><a href="#ios_cache_policy">Specifying the Cache Policy</a></li>
<li class="level1"><a href="#ios_timeout_interval">Specifying a Timeout Interval</a></li>
<li class="level1"><a href="#ios_http_auth">HTTP Authentication</a></li>
<li class="level1"><a href="#ios_example">Examples</a><ul><li class="level2"><a href="#ios_example_calc">Simple Calculator Example (C++)</a><ul><li class="level3"><a href="#ios_calc_step_1">Step 1: Generating stubs for C++ API</a></li>
<li class="level3"><a href="#ios_calc_step_2">Step 2: Creating Xcode project for iPhone</a></li>
<li class="level3"><a href="#ios_calc_step_3">Step 3: Adding generated source stubs to the Xcode project</a></li>
<li class="level3"><a href="#ios_calc_step_4">Step 4: Implementing the Logic by calling the soap service</a></li>
</ul>
</li>
<li class="level2"><a href="#ios_example_geoip">GeoIPService Example (C++)</a><ul><li class="level3"><a href="#ios_geoip_step_1">Step 1: Generating stubs for C++ Proxy</a></li>
<li class="level3"><a href="#ios_geoip_step_2">Step 2: Creating an Xcode project for iPhone</a></li>
<li class="level3"><a href="#ios_geoip_step_3">Step 3: Adding generated source stubs to the Xcode project</a></li>
<li class="level3"><a href="#ios_geoip_step_4">Step 4: Implementing the Logic by calling the soap service</a></li>
</ul>
</li>
<li class="level2"><a href="#ios_example_weather">Weather Example (C++)</a><ul><li class="level3"><a href="#ios_weather_step_1">Step 1: Generating stubs for C++ Proxy</a></li>
<li class="level3"><a href="#ios_weather_step_2">Step 2: Creating an Xcode project for iPhone</a></li>
<li class="level3"><a href="#ios_weather_step_3">Step 3: Adding generated source stubs to the Xcode project</a></li>
<li class="level3"><a href="#ios_weather_step_4">Step 4: Implementing the Logic by calling the soap service</a></li>
</ul>
</li>
<li class="level2"><a href="#ios_example_air">Air Example (C++)</a><ul><li class="level3"><a href="#ios_air_step_1">Step 1: Generating stubs for C++ Proxy</a></li>
<li class="level3"><a href="#ios_air_step_2">Step 2: Creating an Xcode project for iPhone</a></li>
<li class="level3"><a href="#ios_air_step_3">Step 3: Adding generated source stubs to the Xcode project</a></li>
<li class="level3"><a href="#ios_air_step_4">Step 4: Implementing the Logic by calling the soap service</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<div class="textblock"><h1><a class="anchor" id="title"></a>
The iOS Plugin</h1>
<p>By Bethany Sanders, Robert van Engelen, Ning Xie, and Wei Zhang</p>
<h1><a class="anchor" id="ios_overview"></a>
Overview</h1>
<p>Consuming Web services on iOS (iPhone and iPad) platforms is increasingly in demand today. Xcode does not offer built-in tools that make consuming XML Web services easy. This means that detailed knowledge of XML processing is required to send SOAP/XML and XML REST requests to the Web services and parse the XML response. By contrast, the gSOAP toolkit offers an automated XML data binding toolkit for C and C++ to develop SOAP/XML Web services and clients. You can also use the iOS plugin to consume XML-RPC and JSON Web services with the <a href="https://www.genivia.com/doc/xml-rpc-json/html/index.html">XML-RPC &amp; JSON/JSON-Path</a> plugin for gSOAP. The plugin makes it easy to consume Web services on iOS platforms, such as iPhone and iPad. Moreover, the plugin takes advantage of iOS network connectivity by supporting 3G/4G/LTE and wifi.</p>
<p>To use the iOS plugin for development of client applications on iOS platforms, register the plugin with the gSOAP engine context as follows:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;struct soap *soap = soap_new();       // new engine context</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;soap_register_plugin(soap, soap_ios); // register the iOS plugin</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;...</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;soap_destroy(soap); // clean up deserialized data</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;soap_end(soap);     // clean up temporaries</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;soap_free(soap);    // free the context</div></div><!-- fragment --><p>When coding in C++, it is recommended to generate C++ proxy classes with soapcpp2 option -j which are then used to instantiate proxy objects that manage the gSOAP engine context to register with the plugin as follows:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;Proxy proxy;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;soap_register_plugin(proxy.soap, soap_ios);</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;...</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;proxy.destroy();</div></div><!-- fragment --><p>There are no other plugin API calls necessary to make a Web service client application work with iOS. This means that you can develop iOS apps that consume complex SOAP/XML, XML REST, and JSON Web services.</p>
<h1><a class="anchor" id="ios_start"></a>
Getting Started</h1>
<p>To start building Web services client applications for iPhone and/or iPad with gSOAP, you will need:</p>
<ul>
<li>The <a href="http://www.genivia.com/Products/downloads.html">gSOAP toolkit</a> version 2.8.50 or greater;</li>
<li>Xcode with the iOS SDK installed.</li>
</ul>
<p>Developing Web services client applications on iOS is no different than developing these applications on another OS with gSOAP when you use this iOS Plugin.</p>
<p>The steps to create a client application on iOS:</p>
<ul>
<li>Use wsdl2h and soapcpp2 to generate C++ code with client stubs or client proxy classes (soapcpp2 option -j) from WSDL and XSD files;</li>
<li>Create an iOS application project in Xcode;</li>
<li>Add stdsoap2.cpp and stdsoap2.h from the gSOAP package to your iOS project;</li>
<li>Add <a class="el" href="gsoapios_8h.html">gsoapios.h</a> and <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a> that are part of the iOS plugin files to your iOS project;</li>
<li>In your client code create an engine context and register the iOS plugin;</li>
<li>In your client code add the Web service methods invocations that you want, see the wsdl2h-generated header file (first step above) with interface declarations for instructions on how to invoke services.</li>
</ul>
<p>All of the source code files should be of type Objective C++ source. Mixing C files with C++ files will cause errors. Rename .c files to .cpp files as necessary.</p>
<h1><a class="anchor" id="ios_cache_policy"></a>
Specifying the Cache Policy</h1>
<p>The interaction between the client and the Web serviceserver can be controlled by specifying the cache policy. To specify the cache policy, use the API function <code><a class="el" href="gsoapios_8mm.html#a0dd8ddc18b78e14e9978a1369f02d97c" title="Sets cache policy The constants used to specify interaction with the cached responses are: ...">soap_ios_setcachepolicy(struct soap *soap, unsigned int policy)</a></code>. This API function cannot be called before the plugin is registered.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;struct soap *soap = soap_new();</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;soap_register_plugin(soap, soap_ios);</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;// Specify the cache policy for the request</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;soap_ios_setchacepolicy(soap, NSURLRequestReturnCacheDataElseLoad);</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;...</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;soap_destroy(soap); // clean up deserialized data</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;soap_end(soap);     // clean up temporaries</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;soap_free(soap);    // free the context</div></div><!-- fragment --><p>The available cache policies that can be specified are:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;enum {</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;  NSURLRequestUseProtocolCachePolicy = 0,</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;  NSURLRequestReloadIgnoringLocalCacheData = 1,</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;  NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;  NSURLRequestReturnCacheDataElseLoad = 2,</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;  NSURLRequestReturnCacheDataDontLoad = 3,</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  NSURLRequestReloadIgnoringLocalAndRemoteCacheData =4,</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;  NSURLRequestReloadRevalidatingCacheData = 5</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;}</div></div><!-- fragment --><p>The default cache policy is <code>NSURLRequestUseProtocolCachePolicy</code>.</p>
<h1><a class="anchor" id="ios_timeout_interval"></a>
Specifying a Timeout Interval</h1>
<p>The timeout of a network connection can be specified using the API function <code><a class="el" href="gsoapios_8mm.html#a733a36a9b2649b17ba7693fc7cb25325" title="Sets timeout interval. ">soap_ios_settimeoutinterval(struct soap *soap, double seconds)</a></code>:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;struct soap *soap = soap_new();</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;soap_register_plugin(soap, soap_ios);</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;// Specify the timout interval as 30 seconds</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;soap_ios_settimeoutinterval(soap, 30.0);</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;...</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;soap_destroy(soap); // clean up deserialized data</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;soap_end(soap);     // clean up temporaries</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;soap_free(soap);    // free the context</div></div><!-- fragment --><p>The default timeout is 60 seconds.</p>
<h1><a class="anchor" id="ios_http_auth"></a>
HTTP Authentication</h1>
<p>To support authentication when access is denied (HTTP 401 error) when the client tries to connect, enable HTTP authentication as follows.</p>
<p>Basic authentication is simply enabled at the client-side by setting the <code>soap.userid</code> and <code>soap.passwd</code> strings to a username and password, respectively:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;struct soap *soap = soap_new();</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;soap-&gt;userid = &quot;someone&quot;;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;soap-&gt;passwd = &quot;somepass&quot;;</div></div><!-- fragment --><p>When using a generated C++ proxy class:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;Proxy proxy;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;porxy.soap-&gt;userid = &quot;someone&quot;;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;porxy.soap-&gt;passwd = &quot;somepass&quot;;</div></div><!-- fragment --><p>Make sure to <b>never use Basic authentication without HTTPS</b>. HTTPS must be used to ensure that Basic authentication is secure.</p>
<h1><a class="anchor" id="ios_example"></a>
Examples</h1>
<p>This section introduces four examples to demonstrate the development of client applications consuming Web services on iOS platforms, such as iPhone and iPad, by using the gSOAP tools and the iOS plugin.</p>
<p>The first example <a class="el" href="index.html#ios_example_calc">Simple Calculator Example (C++)</a> is a basic calculator client app. The second example <a class="el" href="index.html#ios_example_geoip">GeoIPService Example (C++)</a> is a web service that locates the country of a certain IP Adress. The third example <a class="el" href="index.html#ios_example_weather">Weather Example (C++)</a> returns weather results for well-known US cities, and the fourth example <a class="el" href="index.html#ios_example_air">Air Example (C++)</a> shows information on every airport within a given country.</p>
<p>We assume you already have had some experience developing applications for iPhone and iPad using Xcode with iOS SDK installed. Experience is not required to read on, but helpful in case you get lost in the details of the Xcode iOS SDK.</p>
<p>General recommendations:</p>
<ul>
<li>Rename .m files to .mm files;</li>
<li>Generate a C++ proxy class using soapcpp2 -j, which produces the source code you will need to access the Web service;</li>
<li>Add stdsoap2.cpp and stdsoap2.h from the gSOAP source code tree to your iOS project;</li>
<li>Add <a class="el" href="gsoapios_8h.html">gsoapios.h</a> and <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a> that are part of the iOS plugin files to your iOS project;</li>
<li>In your client code register the iOS plugin.</li>
</ul>
<h2><a class="anchor" id="ios_example_calc"></a>
Simple Calculator Example (C++)</h2>
<p>This example shows you how to develop a client application in C++ using gSOAP and the ios plugin, which consumes a simple calculator service on iOS using gSOAP. The simple calculator service was developed and deployed as a demo to <a href="http://www.genivia.com/dev.html">get started with gSOAP</a>. The gSOAP Calculator Service provides several operations such as add, sub, mul, div etc. In this example, we use the operation add as a demo. Other operations are applied in a similar way. The wsdl file for this service can be obtained at the following link: </p><pre class="fragment">http://www.genivia.com/calc.wsdl
</pre><p>The Xcode project for this example can be found in gsoap/ios_plugin/examples/calc.</p>
<h3><a class="anchor" id="ios_calc_step_1"></a>
Step 1: Generating stubs for C++ API</h3>
<p>The gsoap/ios_plugin/examples/calc directory already contains calc.h so you can skip this step.</p>
<p>To generate codes for the calculator Web service, we first run the wsdl2h tool from the command line on the URL of the WSDL and use option -o to specify the output file (Alternatively, you can download the calc.wsdl and use the local file instead of the URL): </p><pre class="fragment">wsdl2h -o calc.h http://www.genivia.com/calc.wsdl
</pre><p>This generates the calc.h service definition header file with service operation definitions and types for the operation's data. By default, gSOAP assumes you will use C++ with STL.</p>
<p>We have not yet generated the stubs for the API. To do so, run the soapcpp2 compiler: </p><pre class="fragment">soapcpp2 -CL -I$GSOAP_HOME/import calc.h
</pre><p>Option -CL indicates client-side only files (soapcpp2 generates both client and server stubs and skeletons by default). This generates a number of source files for client application development. We do not have to generate a proxy class in this example because it does not use a Proxy class.</p>
<h3><a class="anchor" id="ios_calc_step_2"></a>
Step 2: Creating Xcode project for iPhone</h3>
<p>Launch Xcode, create a Single View-based Application project and name it Calc. Open the ViewController.xib (main storyboard) file in the Interface Builder. Double-click on the View item and populate it with the views listed below and shown in Figure 1:</p>
<ul>
<li>Two Labels ("+" and "A Simple Calculator")</li>
<li>Two Text Fields (operand1 and operand2)</li>
<li>One Button ("Add" button)</li>
</ul>
<div class="image">
<img src="calc-view.png" alt="calc-view.png"/>
<div class="caption">
Figure 1. View of the Calculator Web Service Client App</div></div>
<p> In Xcode, edit the file ViewController.h to make it look like the following:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;// File: ViewController.h</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;@interface ViewController : UIViewController {</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;  UITextField *op1; // operand1</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  UITextField *op2; // operand2</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;}</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;@property (nonatomic, retain) IBOutlet UITextField *op1; // this code is generated when you link the text fields</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;@property (nonatomic, retain) IBOutlet UITextField *op2; // this code is generated when you link the text fields</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;- (IBAction) buttonPressed;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;@end</div></div><!-- fragment --><p>Link the op1 and op2 to the two Text Fields and delegate the button action to method buttonPressed.</p>
<p>In Xcode, edit the file info.plist to make it look like the following: </p><pre class="fragment">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
  &lt;dict&gt;
    &lt;key&gt;NSAppTransportSecurity&lt;/key&gt;
    &lt;dict&gt;
      &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt;
      &lt;true/&gt;
    &lt;/dict&gt;
    &lt;key&gt;CFBundleDevelopmentRegion&lt;/key&gt;
    &lt;string&gt;en&lt;/string&gt;
    &lt;key&gt;CFBundleExecutable&lt;/key&gt;
    &lt;string&gt;$(EXECUTABLE_NAME)&lt;/string&gt;
    &lt;key&gt;CFBundleIdentifier&lt;/key&gt;
    &lt;string&gt;$(PRODUCT_BUNDLE_IDENTIFIER)&lt;/string&gt;
    &lt;key&gt;CFBundleInfoDictionaryVersion&lt;/key&gt;
    &lt;string&gt;6.0&lt;/string&gt;
    &lt;key&gt;CFBundleName&lt;/key&gt;
    &lt;string&gt;$(PRODUCT_NAME)&lt;/string&gt;
    &lt;key&gt;CFBundlePackageType&lt;/key&gt;
    &lt;string&gt;APPL&lt;/string&gt;
    &lt;key&gt;CFBundleShortVersionString&lt;/key&gt;
    &lt;string&gt;1.0&lt;/string&gt;
    &lt;key&gt;CFBundleSignature&lt;/key&gt;
    &lt;string&gt;????&lt;/string&gt;
    &lt;key&gt;CFBundleVersion&lt;/key&gt;
    &lt;string&gt;1&lt;/string&gt;
    &lt;key&gt;LSRequiresIPhoneOS&lt;/key&gt;
    &lt;true/&gt;
    &lt;key&gt;UILaunchStoryboardName&lt;/key&gt;
    &lt;string&gt;LaunchScreen&lt;/string&gt;
    &lt;key&gt;UIMainStoryboardFile&lt;/key&gt;
    &lt;string&gt;Main&lt;/string&gt;
    &lt;key&gt;UIRequiredDeviceCapabilities&lt;/key&gt;
    &lt;array&gt;
      &lt;string&gt;armv7&lt;/string&gt;
    &lt;/array&gt;
    &lt;key&gt;UISupportedInterfaceOrientations&lt;/key&gt;
    &lt;array&gt;
      &lt;string&gt;UIInterfaceOrientationPortrait&lt;/string&gt;
      &lt;string&gt;UIInterfaceOrientationLandscapeLeft&lt;/string&gt;
      &lt;string&gt;UIInterfaceOrientationLandscapeRight&lt;/string&gt;
    &lt;/array&gt;
  &lt;/dict&gt;
&lt;/plist&gt;
</pre><p>These changes ensure that you can access the web services despite the added layer of protection (App Transport Security).</p>
<h3><a class="anchor" id="ios_calc_step_3"></a>
Step 3: Adding generated source stubs to the Xcode project</h3>
<p>Add the source files soapC.cpp, soapClient.cpp, soapH.h, and soapStub.h generated in Step 1 of this tutorial to the project. Also add files stdsoap2.h and stdsoap2.cpp to the project from gSOAP package as well as the iOS plugin files <a class="el" href="gsoapios_8h.html">gsoapios.h</a> and <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a>.</p>
<p>Once all of your files have been added to the project, ensure they are all of type "Objective C++ Source". This ensures that there will be no issues with mixing Objective C and C++ code.</p>
<h3><a class="anchor" id="ios_calc_step_4"></a>
Step 4: Implementing the Logic by calling the soap service</h3>
<p>Firstly, edit file main.mm to import the file calc.nsmap. Link errors may arise without importing this XML namespace mapping table.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;// File: main.mm</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;#import &quot;../../calc.nsmap&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;int main(int argc, char * argv[]) {</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;  @autoreleasepool {</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;  }</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;}</div></div><!-- fragment --><p>Then, implement the source file ViewController.mm as the following:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;ViewController.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;#import &quot;soapStub.h&quot;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;@implementation ViewController</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;@synthesize op1; // Set or get operand1</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;@synthesize op2; // Set or get operand2</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;- (IBAction) buttonPressed {</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;  double x = [op1.text doubleValue];</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;  double y = [op2.text doubleValue];</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;  struct soap *soap = soap_new1(SOAP_IO_DEFAULT|SOAP_IO_KEEPALIVE|SOAP_XML_INDENT|SOAP_XML_STRICT);</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;  if (soap_register_plugin(soap, soap_ios) == SOAP_OK)</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;  {</div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;    // Specify the timeout interval (optional) to 45 seconds instead of</div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;    // the default 60 seconds</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;    soap_ios_settimeoutinterval(soap, 45.0);</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;    double result;</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;    // Call Web service operation add</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;    int status = soap_call_ns2__add(soap, NULL, NULL,x, y, result);</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;    soap_free_temp(soap); // Cleanup temporary resources</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;    // Check soap response status</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;    if (status == SOAP_OK)</div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;    {</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;      NSString *resultString;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;      NSString *titleString;</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;      resultString = [NSString stringWithFormat:@&quot;%f&quot;,result];</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;      titleString = [NSString stringWithFormat:@&quot;%f + %f =&quot;,x, y];</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;      // Show the result in an alert</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;      UIAlertController * alert = [UIAlertController</div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;        alertControllerWithTitle:titleString</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;        message:resultString</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;        preferredStyle:UIAlertControllerStyleAlert];</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;      UIAlertAction* cancelButton = [UIAlertAction</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;        actionWithTitle:@&quot;OK&quot;</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;        style:UIAlertActionStyleDefault</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;        handler:^(UIAlertAction * action){}];</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;      [alert addAction: cancelButton];</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;      [self presentViewController:alert animated:YES completion:nil];</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;    }</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;    else</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;      soap_print_fault(soap,stderr); // Print soap error in console</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;  }</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;  soap_destroy(soap);</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;  soap_end(soap);</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;  soap_free(soap);</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;}</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;@end</div></div><!-- fragment --><p>A screen snapshot of the client is shown in Figure 2.</p>
<div class="image">
<img src="calc-result.png" alt="calc-result.png"/>
<div class="caption">
Figure 2: Snapshot of the CalcViewService result</div></div>
 <h2><a class="anchor" id="ios_example_geoip"></a>
GeoIPService Example (C++)</h2>
<p><a href="http://www.webservicex.net/geoipservice.asmx?op=GetGeoIP">GeoIPService</a> is a live SOAP Web service that enables you to look up countries by IP address or by Context.</p>
<p>This example shows you how to develop a client application in C++ using gSOAP and the ios plugin, which consumes the GeoIPService on iOS using gSOAP. The WSDL file for this service can be downloaded at the following link: </p><pre class="fragment">http://www.webservicex.net/geoipservice.asmx?WSDL
</pre><p>It is crucial to follow these directions in order for your app to work:</p>
<ul>
<li>Rename the .m files to .mm files. The iOS plugin implementation file gsoapios.m must be renamed to <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a>. The main.m must be renamed to main.mm. Other files such as your ViewController must also be renamed with .mm.</li>
<li>Generate C++ proxy using proper options with wsdl2h and soapcpp2.</li>
<li>Use stdsoap2.cpp from the gSOAP package in your iOS project.</li>
</ul>
<p>The Xcode project for this example can be found in gsoap/ios_plugin/examples/GeoIPService.</p>
<h3><a class="anchor" id="ios_geoip_step_1"></a>
Step 1: Generating stubs for C++ Proxy</h3>
<p>To generate codes for the GeoIPService Web service, we first run the wsdl2h tool from the command line on the URL of the WSDL and use option -o to specify the output file (alternatively, you can download the GeoIPService.wsdl file and use the local file instead of the URL): </p><pre class="fragment">wsdl2h -o GeoIPService.h -Ngeoip 'http://www.webservicex.net/geoipservice.asmx?WSDL'
</pre><p>This generates the GeoIPService.h service interface header file with service operation definitions and types for the operation's data. By default, gSOAP assumes you will use C++ with STL.</p>
<p>To generate the stubs for the C++ proxy classes, run the soapcpp2: </p><pre class="fragment">soapcpp2 -j -CL -I$GSOAP_HOME/import GeoIPService.h
</pre><p>Option -j tells the compiler to generate the C++ proxy class and option -CL indicates client-side only files (soapcpp2 generates both client and server stubs and skeletons by default). Option -I is needed to import the stlvector.h file from the import directory in the gSOAP package to support serialization of STL vectors.</p>
<h3><a class="anchor" id="ios_geoip_step_2"></a>
Step 2: Creating an Xcode project for iPhone</h3>
<p>Create a Single View-based Application project and name it GeoIPService.Open the ViewController.xib (main storyboard) file in the Interface Builder. Double-click on the View item and populate it with the views listed below and shown in Figure 3:</p>
<ul>
<li>A Label ("Enter IP Address")</li>
<li>A Text Field</li>
<li>One Round Rect Button ("Find Country" button)</li>
</ul>
<div class="image">
<img src="geoip-view.png" alt="geoip-view.png"/>
<div class="caption">
Figure 3. View of the GeoIPService Client</div></div>
<p> In Xcode, edit the file ViewController.h to make it look like the following:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;// File: ViewController.h</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;@interface ViewController : UIViewController {</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;  UITextField* IPAddress;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;}</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;@property (strong, nonatomic) IBOutlet UITextField *IPAddress; // this code generated when you link the text</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;//field to IPAddress</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;- (IBAction) buttonPressed;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;@end</div></div><!-- fragment --><p>Set the ipAddress outlet and the buttonFindCountry:(id)sender method to delegate action of the button.</p>
<p>In Xcode, edit the file info.plist to make it look like the following: </p><pre class="fragment">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
  &lt;dict&gt;
    &lt;key&gt;NSAppTransportSecurity&lt;/key&gt;
    &lt;dict&gt;
      &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt;
      &lt;true/&gt;
    &lt;/dict&gt;
      &lt;key&gt;CFBundleDevelopmentRegion&lt;/key&gt;
      &lt;string&gt;en&lt;/string&gt;
      &lt;key&gt;CFBundleExecutable&lt;/key&gt;
      &lt;string&gt;$(EXECUTABLE_NAME)&lt;/string&gt;
      &lt;key&gt;CFBundleIdentifier&lt;/key&gt;
      &lt;string&gt;$(PRODUCT_BUNDLE_IDENTIFIER)&lt;/string&gt;
      &lt;key&gt;CFBundleInfoDictionaryVersion&lt;/key&gt;
      &lt;string&gt;6.0&lt;/string&gt;
      &lt;key&gt;CFBundleName&lt;/key&gt;
      &lt;string&gt;$(PRODUCT_NAME)&lt;/string&gt;
      &lt;key&gt;CFBundlePackageType&lt;/key&gt;
      &lt;string&gt;APPL&lt;/string&gt;
      &lt;key&gt;CFBundleShortVersionString&lt;/key&gt;
      &lt;string&gt;1.0&lt;/string&gt;
      &lt;key&gt;CFBundleSignature&lt;/key&gt;
      &lt;string&gt;????&lt;/string&gt;
      &lt;key&gt;CFBundleVersion&lt;/key&gt;
      &lt;string&gt;1&lt;/string&gt;
      &lt;key&gt;LSRequiresIPhoneOS&lt;/key&gt;
      &lt;true/&gt;
      &lt;key&gt;UILaunchStoryboardName&lt;/key&gt;
      &lt;string&gt;LaunchScreen&lt;/string&gt;
      &lt;key&gt;UIMainStoryboardFile&lt;/key&gt;
      &lt;string&gt;Main&lt;/string&gt;
      &lt;key&gt;UIRequiredDeviceCapabilities&lt;/key&gt;
      &lt;array&gt;
        &lt;string&gt;armv7&lt;/string&gt;
      &lt;/array&gt;
      &lt;key&gt;UISupportedInterfaceOrientations&lt;/key&gt;
      &lt;array&gt;
        &lt;string&gt;UIInterfaceOrientationPortrait&lt;/string&gt;
        &lt;string&gt;UIInterfaceOrientationLandscapeLeft&lt;/string&gt;
        &lt;string&gt;UIInterfaceOrientationLandscapeRight&lt;/string&gt;
      &lt;/array&gt;
  &lt;/dict&gt;
&lt;/plist&gt;
</pre><p>These changes ensure that you can access the web services despite the added layer of protection of App Transport Security).</p>
<h3><a class="anchor" id="ios_geoip_step_3"></a>
Step 3: Adding generated source stubs to the Xcode project</h3>
<p>Add the source files soapC.cpp, soapGeoIPServiceSoapProxy.cpp, soapGeoIPServiceSoapProxy.h, soapH.h, and soapStub.h generated in Step 1 of this tutorial to the project. Also add files stdsoap2.h and stdsoap2.cpp to the project from the gSOAP package and the iOS plugin files <a class="el" href="gsoapios_8h.html">gsoapios.h</a> and <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a>.</p>
<p>Once all of your files have been added to the project, ensure they are all of type "Objective C++ Source". This ensures that there will be no issues with mixing Objective C and C++ code.</p>
<h3><a class="anchor" id="ios_geoip_step_4"></a>
Step 4: Implementing the Logic by calling the soap service</h3>
<p>Firstly, edit file main.mm to import the file GeoIPService.nsmap. Linking errors would arise without importing this XML namespace mapping table.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;// File: main.mm</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;#import &quot;AppDelegate.h&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;#include &quot;../../GeoIPServiceSoap.nsmap&quot;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;int main(int argc, char * argv[]) {</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;  @autoreleasepool {</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;  }</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;}</div></div><!-- fragment --><p>Then, implement the source file ViewController.mm as the following:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;ViewController.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;#include &quot;soapGeoIPServiceSoapProxy.h&quot;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &quot;soapStub.h&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;using namespace std;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;typedef struct _ns1__GetGeoIP RequestStruct;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;typedef struct _ns1__GetGeoIPResponse ResponseStruct;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;@implementation ViewController</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;@synthesize IPAddress;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;- (IBAction)buttonPressed:(id)sender {</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;  RequestStruct ip;</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;  ResponseStruct response;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;</div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;  //creates proxy</div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;  GeoIPServiceSoapProxy service(SOAP_IO_DEFAULT|SOAP_IO_KEEPALIVE|SOAP_XML_INDENT|SOAP_XML_STRICT);</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;  soap_init(service.soap);</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;  //sets IPAddress from input</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;  std::string ipAdd = std::string((char *)[IPAddress.text UTF8String]);</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;  ip.IPAddress = &amp;ipAdd;</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;  // ----- register plugin for callbacks ------</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;  soap_register_plugin(service.soap, soap_ios);</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;  // Optional: timeout internal, the default is 60.0 seconds</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;  soap_ios_settimeoutinterval(service.soap, 30.0);</div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;  //call web service</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;  int status = service.GetGeoIP(&amp;ip, response);</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;  string* result;</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;  string err_msg = &quot;Invalid IP address&quot;;</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;  if (status == SOAP_OK)</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;  {</div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;    NSString *soapResult;</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;    NSString *titleMsg;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;    if (response.GetGeoIPResult &amp;&amp; response.GetGeoIPResult-&gt;CountryName)</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;      result = response.GetGeoIPResult-&gt;CountryName;</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;    else</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;      result = &amp;err_msg;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;    soapResult = [NSString stringWithUTF8String:result-&gt;c_str()];</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;    titleMsg = [NSString stringWithFormat: @&quot;%@&quot;, @&quot;Country Found&quot;];</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;    //show result as an alert</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;    UIAlertController * alert = [UIAlertController</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;      alertControllerWithTitle:titleMsg</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;      message:soapResult</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;      preferredStyle:UIAlertControllerStyleAlert];</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;    UIAlertAction* cancelButton = [UIAlertAction</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;      actionWithTitle:@&quot;OK&quot;</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;      style:UIAlertActionStyleDefault</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;      handler:^(UIAlertAction * action){}];</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;</div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;    [alert addAction: cancelButton];</div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;    [self presentViewController:alert animated:YES completion:nil];</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;</div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;  }</div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;  else</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;    service.soap_stream_fault(std::cerr);</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;  service.destroy();</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;}</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;// Override to allow orientations other than the default portrait orientation.</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;  // Return YES for supported orientations</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;  return (interfaceOrientation == UIInterfaceOrientationPortrait ||</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;      interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown ||</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;      interfaceOrientation == UIInterfaceOrientationLandscapeLeft ||</div><div class="line"><a name="l00076"></a><span class="lineno">   76</span>&#160;      interfaceOrientation == UIInterfaceOrientationLandscapeRight);</div><div class="line"><a name="l00077"></a><span class="lineno">   77</span>&#160;}</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;</div><div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;- (void)didReceiveMemoryWarning {</div><div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;  // Releases the view if it doesn&#39;t have a superview.</div><div class="line"><a name="l00081"></a><span class="lineno">   81</span>&#160;  [super didReceiveMemoryWarning];</div><div class="line"><a name="l00082"></a><span class="lineno">   82</span>&#160;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;  // Release any cached data, images, etc that aren&#39;t in use.</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;}</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;- (void)viewDidUnload {</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;  // Release any retained subviews of the main view.</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;  // e.g. self.myOutlet = nil;</div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;}</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;- (void)dealloc {</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;  //    [ipAddress release];</div><div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;  //    [super dealloc];</div><div class="line"><a name="l00094"></a><span class="lineno">   94</span>&#160;}</div><div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;@end</div></div><!-- fragment --><p>An image of the app is shown in Figure 4.</p>
<div class="image">
<img src="geoip-result.png" alt="geoip-result.png"/>
<div class="caption">
Figure 4: Snapshot of the GeoIPServiceViewService result</div></div>
 <h2><a class="anchor" id="ios_example_weather"></a>
Weather Example (C++)</h2>
<p>GlobalWeather is a live SOAP Web service that enables you to look up the Weather in popular cities around the world. For simplicity, this example is limited to cities in the United States. For some reason, some very popular cities are not supported by this web service. For example, no results for New York City will be returned. There is an error message within the app that shows whenever one of these cities is entered. Know that the error message is not an issue with the app you just built, but something that the web service itself does not provide.</p>
<p>This example shows how to develop a client application in C++ using gSOAP and the ios plugin, which consumes the Weather service on iOS using gSOAP. The WSDL file for this service can be downloaded at the following link: </p><pre class="fragment">http://www.webservicex.net/globalweather.asmx?WSDL
</pre><p>It is crucial to follow these directions in order for your app to work:</p>
<ul>
<li>Rename the .m files to .mm files. The iOS plugin implementation file gsoapios.m must be renamed to <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a>. The main.m must be renamed to main.mm. Other files such as your ViewController must also be renamed with .mm.</li>
<li>Generate C++ proxy using proper options with wsdl2h and soapcpp2.</li>
<li>Use stdsoap2.cpp from the gSOAP package in your iOS project.</li>
</ul>
<p>The Xcode project for this example can be found in gsoap/ios_plugin/examples/Weather.</p>
<h3><a class="anchor" id="ios_weather_step_1"></a>
Step 1: Generating stubs for C++ Proxy</h3>
<p>To generate codes for the GeoIPService Web service, we first run the wsdl2h tool from the command line on the URL of the WSDL and use option -o to specify the output file (Alternatively, you can download the GlobalWeather.wsdl file and use the local file instead of the URL): </p><pre class="fragment">wsdl2h -o weather.h 'http://www.webservicex.net/globalweather.asmx?WSDL'
</pre><p>This generates the weather.h service definition header file with service operation definitions and types for the operation's data. By default, gSOAP assumes you will use C++ with STL.</p>
<p>Because we will be using the gSOAP DOM parser in this example, which is created in our program with <code>xsd__anyType dom(ctx)</code> to extract plain XML content received in string <code>xmlmessage</code> with <code>xmlmessage &gt;&gt; dom</code>, an additional step is necessary. Add the following line to the wsdl2h-generated airport.h file: </p><pre class="fragment">#import "dom.h"
</pre><p>To generate the stubs for the C++ proxy classes, run the soapcpp2 tool: </p><pre class="fragment">soapcpp2 -j -CL -I$GSOAP_HOME/import weather.h
</pre><p>Option -j tells soapcpp2 to generate the C++ proxy class and option -CL indicates client-side only files (soapcpp2 generates both client and server stubs and skeletons by default). Option -I is needed to import the stlvector.h file from the import directory in the gSOAP package to support serialization of STL vectors.</p>
<h3><a class="anchor" id="ios_weather_step_2"></a>
Step 2: Creating an Xcode project for iPhone</h3>
<p>Create a Single View-based Application project and name it Weather. Open the ViewController.xib(main storyboard) file in the Interface Builder.Double-click on the View item and populate it with the views listed below and shown in Figure 3:</p>
<ul>
<li>A Label ("Enter US City")</li>
<li>A Text Field</li>
<li>One Round Rect Button ("Get Weather Results" button)</li>
</ul>
<p>In Xcode, edit the file ViewController.h to make it look like the following:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;@interface ViewController : UIViewController {</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;    UITextField* inputcity;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;}</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;@property (strong, nonatomic) IBOutlet UITextField *inputcity;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;- (IBAction) buttonPressed;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;@end</div></div><!-- fragment --><p>Set the inputcity outlet and the buttonFindCountry:(id)sender method to delegate action of the button.</p>
<p>In Xcode, edit the file info.plist to make it look like the following: </p><pre class="fragment"> &lt;?xml version="1.0" encoding="UTF-8"?&gt;
 &lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
 &lt;plist version="1.0"&gt;
   &lt;dict&gt;
     &lt;key&gt;NSAppTransportSecurity&lt;/key&gt;
     &lt;dict&gt;
       &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt;
       &lt;true/&gt;
     &lt;/dict&gt;
       &lt;key&gt;CFBundleDevelopmentRegion&lt;/key&gt;
       &lt;string&gt;en&lt;/string&gt;
       &lt;key&gt;CFBundleExecutable&lt;/key&gt;
       &lt;string&gt;$(EXECUTABLE_NAME)&lt;/string&gt;
       &lt;key&gt;CFBundleIdentifier&lt;/key&gt;
       &lt;string&gt;$(PRODUCT_BUNDLE_IDENTIFIER)&lt;/string&gt;
       &lt;key&gt;CFBundleInfoDictionaryVersion&lt;/key&gt;
       &lt;string&gt;6.0&lt;/string&gt;
       &lt;key&gt;CFBundleName&lt;/key&gt;
       &lt;string&gt;$(PRODUCT_NAME)&lt;/string&gt;
       &lt;key&gt;CFBundlePackageType&lt;/key&gt;
       &lt;string&gt;APPL&lt;/string&gt;
       &lt;key&gt;CFBundleShortVersionString&lt;/key&gt;
       &lt;string&gt;1.0&lt;/string&gt;
       &lt;key&gt;CFBundleSignature&lt;/key&gt;
       &lt;string&gt;????&lt;/string&gt;
       &lt;key&gt;CFBundleVersion&lt;/key&gt;
       &lt;string&gt;1&lt;/string&gt;
       &lt;key&gt;LSRequiresIPhoneOS&lt;/key&gt;
       &lt;true/&gt;
       &lt;key&gt;UILaunchStoryboardName&lt;/key&gt;
       &lt;string&gt;LaunchScreen&lt;/string&gt;
       &lt;key&gt;UIMainStoryboardFile&lt;/key&gt;
       &lt;string&gt;Main&lt;/string&gt;
       &lt;key&gt;UIRequiredDeviceCapabilities&lt;/key&gt;
       &lt;array&gt;
         &lt;string&gt;armv7&lt;/string&gt;
       &lt;/array&gt;
       &lt;key&gt;UISupportedInterfaceOrientations&lt;/key&gt;
       &lt;array&gt;
         &lt;string&gt;UIInterfaceOrientationPortrait&lt;/string&gt;
         &lt;string&gt;UIInterfaceOrientationLandscapeLeft&lt;/string&gt;
         &lt;string&gt;UIInterfaceOrientationLandscapeRight&lt;/string&gt;
       &lt;/array&gt;
  &lt;/dict&gt;
&lt;/plist&gt;
</pre><p>These changes ensure that you can access the web services despite the added layer of protection of App Transport Security).</p>
<h3><a class="anchor" id="ios_weather_step_3"></a>
Step 3: Adding generated source stubs to the Xcode project</h3>
<p>Add the source files soapC.cpp, soapGloabalWeatherSoapProxy.cpp, soapGloabalWeatherSoapProxy.h, soapH.h, and soapStub.h generated in Step 1 of this tutorial to the project. Also add files stdsoap2.h and stdsoap2.cpp to the project from gsoap package and the iOS plugin files <a class="el" href="gsoapios_8h.html">gsoapios.h</a> and <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a>.</p>
<p>Once all of your files have been added to the project, ensure they are all of type "Objective C++ Source". This ensures that there will be no issues with mixing Objective C and C++ code.</p>
<h3><a class="anchor" id="ios_weather_step_4"></a>
Step 4: Implementing the Logic by calling the soap service</h3>
<p>Firstly, edit file main.mm to import the file GlobalWeatherSoap.nsmap. Linking errors would arise without importing this XML namespace mapping table.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;// File: main.mm</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;#import &quot;AppDelegate.h&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;#include &quot;../../GlobalWeatherSoap.nsmap&quot;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;int main(int argc, char * argv[]) {</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;   @autoreleasepool {</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;     return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;   }</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;}</div></div><!-- fragment --><p>Then, implement the source file ViewController.mm as the following, where we used the <a href="http://www.genivia.com/doc/dom/html">gSOAP domcpp</a> tool with option -i on an example weather XML data file to produce DOM code to extract the XML data (see further below):</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;ViewController.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;#include &quot;soapGlobalWeatherSoapProxy.h&quot;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &quot;soapStub.h&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;#include &lt;fstream&gt;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;typedef struct _ns__GetWeather RequestStruct;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;typedef struct _ns__GetWeatherResponse ResponseStruct;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;@implementation ViewController</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;@synthesize inputcity;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;- (IBAction)buttonPressed:(id)sender {</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;  RequestStruct sending;</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;  ResponseStruct receiving;</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;  std::string result = &quot;&quot;;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;</div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;  GlobalWeatherSoapProxy service;</div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;  soap_init(service.soap);</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;  // ----- register plugin for callbacks ------</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;  soap_register_plugin(service.soap, soap_ios);</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;  std::string cname= std::string((char *)[inputcity.text UTF8String]);</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;  sending.CityName = &amp;cname;</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;  std::string USA = &quot;United States&quot;;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;  sending.CountryName = &amp;USA;</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;  if (service.GetWeather(&amp;sending, receiving) == SOAP_OK)</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;  {</div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;    std::ofstream xmlwrite(&quot;/Users/bethanysanders/Documents/work/Weather/Weather/message.txt&quot;);</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;    std::ifstream xmlread(&quot;/Users/bethanysanders/Documents/work/Weather/Weather/message.txt&quot;);</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;    if(xmlwrite.is_open())</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;    {</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;      xmlwrite &lt;&lt; *(receiving.GetWeatherResult);</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;      xmlwrite.close();</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;      struct soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;      ctx-&gt;double_format = &quot;%lG&quot;;</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;      xsd__anyType dom(ctx);</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;      if (xmlread.is_open())</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;        xmlread &gt;&gt; dom;</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;      if (dom.soap-&gt;error)</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;        result = &quot;Error: Try a different city&quot;;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;      xsd__anyAttribute *att;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;      xsd__anyType *elt;</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;      if ((elt = dom.elt_get(&quot;Wind&quot;)))</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;      {</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;        xsd__anyType&amp; dom_Wind = *elt;</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;        if (dom_Wind.get_text())</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;        {</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;          result += &quot;Wind = &quot;;</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;          result += dom_Wind.get_text();</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;        }</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;      }</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;      if ((elt = dom.elt_get(&quot;Visibility&quot;)))</div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;      {</div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;        xsd__anyType&amp; dom_Visibility = *elt;</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;        if(dom_Visibility.get_text())</div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;        {</div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;          result += &quot;\nVisibility = &quot;;</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;          result += dom_Visibility.get_text();</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;        }</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;      }</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;      if ((elt = dom.elt_get(&quot;SkyConditions&quot;)))</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;      {</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;        xsd__anyType&amp; dom_SkyConditions = *elt;</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;        if (dom_SkyConditions.get_text())</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;        {</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;          result += &quot;\nSky Conditions = &quot;;</div><div class="line"><a name="l00076"></a><span class="lineno">   76</span>&#160;          result += dom_SkyConditions.get_text();</div><div class="line"><a name="l00077"></a><span class="lineno">   77</span>&#160;        }</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;      }</div><div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;      if ((elt = dom.elt_get(&quot;Temperature&quot;)))</div><div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;      {</div><div class="line"><a name="l00081"></a><span class="lineno">   81</span>&#160;        xsd__anyType&amp; dom_Temperature = *elt;</div><div class="line"><a name="l00082"></a><span class="lineno">   82</span>&#160;        if (dom_Temperature.get_text())</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;        {</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;          result += &quot;\nTemperature = &quot;;</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;          result += dom_Temperature.get_text();</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;        }</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;      }</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;      if ((elt = dom.elt_get(&quot;DewPoint&quot;)))</div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;      {</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;        xsd__anyType&amp; dom_DewPoint = *elt;</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;        if (dom_DewPoint.get_text())</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;        {</div><div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;          result += &quot;\nDew Point = &quot;;</div><div class="line"><a name="l00094"></a><span class="lineno">   94</span>&#160;          result += dom_DewPoint.get_text();</div><div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;        }</div><div class="line"><a name="l00096"></a><span class="lineno">   96</span>&#160;      }</div><div class="line"><a name="l00097"></a><span class="lineno">   97</span>&#160;      if ((elt = dom.elt_get(&quot;RelativeHumidity&quot;)))</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;      {</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;        xsd__anyType&amp; dom_RelativeHumidity = *elt;</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;        if (dom_RelativeHumidity.get_text())</div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;        {</div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;          result += &quot;\nRelative Humidity = &quot;;</div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;          result += dom_RelativeHumidity.get_text();</div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;        }</div><div class="line"><a name="l00105"></a><span class="lineno">  105</span>&#160;      }</div><div class="line"><a name="l00106"></a><span class="lineno">  106</span>&#160;      if ((elt = dom.elt_get(&quot;Pressure&quot;)))</div><div class="line"><a name="l00107"></a><span class="lineno">  107</span>&#160;      {</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;        xsd__anyType&amp; dom_Pressure = *elt;</div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;        if (dom_Pressure.get_text())</div><div class="line"><a name="l00110"></a><span class="lineno">  110</span>&#160;        {</div><div class="line"><a name="l00111"></a><span class="lineno">  111</span>&#160;          result += &quot;\nPressure = &quot;;</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;          result += dom_Pressure.get_text();</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;        }</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;      }</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;</div><div class="line"><a name="l00116"></a><span class="lineno">  116</span>&#160;      xmlread.close();</div><div class="line"><a name="l00117"></a><span class="lineno">  117</span>&#160;</div><div class="line"><a name="l00118"></a><span class="lineno">  118</span>&#160;      soap_destroy(ctx); // delete objects</div><div class="line"><a name="l00119"></a><span class="lineno">  119</span>&#160;      soap_end(ctx);     // delete DOM data</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;      soap_free(ctx);    // free context</div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;    }</div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;  }</div><div class="line"><a name="l00123"></a><span class="lineno">  123</span>&#160;</div><div class="line"><a name="l00124"></a><span class="lineno">  124</span>&#160;  NSString *titleMsg;</div><div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;  NSString *Weather;</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;  titleMsg = [NSString stringWithFormat: @&quot;%@&quot;, @&quot;Weather Results&quot;];</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;  Weather = [NSString stringWithUTF8String:result.c_str()];</div><div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;</div><div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;  //show result as an alert</div><div class="line"><a name="l00130"></a><span class="lineno">  130</span>&#160;  UIAlertController * alert = [UIAlertController</div><div class="line"><a name="l00131"></a><span class="lineno">  131</span>&#160;    alertControllerWithTitle:titleMsg</div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;    message:Weather</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;    preferredStyle:UIAlertControllerStyleAlert];</div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;  UIAlertAction* cancelButton = [UIAlertAction</div><div class="line"><a name="l00135"></a><span class="lineno">  135</span>&#160;    actionWithTitle:@&quot;OK&quot;</div><div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;    style:UIAlertActionStyleDefault</div><div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;    handler:^(UIAlertAction * action){}];</div><div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;</div><div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;  [alert addAction: cancelButton];</div><div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;  [self presentViewController:alert animated:YES completion:nil];</div><div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;</div><div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;  service.destroy();</div><div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;}</div><div class="line"><a name="l00144"></a><span class="lineno">  144</span>&#160;</div><div class="line"><a name="l00145"></a><span class="lineno">  145</span>&#160;- (void)viewDidLoad {</div><div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;    [super viewDidLoad];</div><div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;    // Do any additional setup after loading the view, typically from a nib.</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;}</div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;</div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;- (void)didReceiveMemoryWarning {</div><div class="line"><a name="l00151"></a><span class="lineno">  151</span>&#160;    [super didReceiveMemoryWarning];</div><div class="line"><a name="l00152"></a><span class="lineno">  152</span>&#160;    // Dispose of any resources that can be recreated.</div><div class="line"><a name="l00153"></a><span class="lineno">  153</span>&#160;}</div><div class="line"><a name="l00154"></a><span class="lineno">  154</span>&#160;</div><div class="line"><a name="l00155"></a><span class="lineno">  155</span>&#160;@end</div></div><!-- fragment --><p>You will notice there is much more code in this example's ViewController.mm. This is because this web service stores the whole XML response within a string instead of appropriate variables. The dom parser can fix this situation so that you can still access your results without having to parse the XML yourself. The dom code in this example was generated via command line in UNIX. To do so, once you have dom executable in your working directory, just execute the command </p><pre class="fragment">./domcpp -i weather.xml
</pre><p>where weather.xml is a file that stores an example xml response. Option -i tells the domcpp tool to generate the code you need to parse your result. To obtain an example XML response, test the web service on <a href="http://www.webservicex.net/New/Home/ServiceDetail/56">http://www.webservicex.net/New/Home/ServiceDetail/56</a>.</p>
<p>The domcpp tool is found in gsoap/samples/dom and should be built in that directory with: </p><pre class="fragment">make domcpp
</pre><p>Then move or copy the domcpp executable to use it for your projects.</p>
<p>For more information about domcpp, read <a href="https://www.genivia.com/doc/dom/html/index.html">XML DOM and XPath</a> of the gSOAP documentation.</p>
<h2><a class="anchor" id="ios_example_air"></a>
Air Example (C++)</h2>
<p>Airport Information Web Service is a live SOAP Web service that enables you to look up Airport Information of countries around the world. For some reason, some very well known countries are not supported by this web service. For example, no results for Russia will be returned. There is an error message within the app that shows whenever one of these countries is entered. Know that the error message is not an issue with the app you just built, but information that the web service itself does not provide.</p>
<p>This example shows how to develop a client application in C++ using gSOAP and the ios plugin, which consumes the Weather service on iOS using gSOAP. The WSDL file for this service can be downloaded at the following link: <a href="http://www.webservicex.net/airport.asmx?WSDL">http://www.webservicex.net/airport.asmx?WSDL</a></p>
<p>It is crucial to follow these directions in order for your app to work:</p>
<ul>
<li>Rename the .m files to .mm files. The iOS plugin implementation file gsoapios.m must be renamed to <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a>. The main.m must be renamed to main.mm. Other files such as your ViewController must also be renamed with .mm.</li>
<li>Generate C++ proxy using proper options with wsdl2h and soapcpp2.</li>
<li>Use the stdsoap2.cpp instead of stdsoap2.c from the gSOAP package in your iOS project.</li>
</ul>
<p>The Xcode project for this example can be found in gsoap/ios_plugin/examples/Air.</p>
<h3><a class="anchor" id="ios_air_step_1"></a>
Step 1: Generating stubs for C++ Proxy</h3>
<p>To generate codes for the GeoIPService Web service, we first run the wsdl2h tool from the command line on the URL of the WSDL and use option -o to specify the output file (Alternatively, you can download the airport.wsdl file and use the local file instead of the URL): </p><pre class="fragment">wsdl2h -o airport.h 'http://www.webservicex.net/airport.asmx?WSDL'
</pre><p>This generates the airport.h service definition header file with service operation definitions and types for the operation's data. By default, gSOAP assumes you will use C++ with STL.</p>
<p>Because we will be using the gSOAP DOM parser in this example, which is created in our program with <code>xsd__anyType dom(ctx)</code> to extract plain XML content received in string <code>xmlmessage</code> with <code>xmlmessage &gt;&gt; dom</code>, an additional step is necessary. Add the following line to the wsdl2h-generated airport.h file: </p><pre class="fragment">#import "dom.h"
</pre><p>To generate the stubs for the C++ proxy classes, run the soapcpp2: </p><pre class="fragment">soapcpp2 -j -CL -I$GSOAP_HOME/import airport.h
</pre><p>Option -j tells the compiler to generate the C++ proxy class and option -CL indicates client-side only files (soapcpp2 generates both client and server stubs and skeletons by default). Option -I is needed to import the stlvector.h file from the import directory in the gSOAP package to support serialization of STL vectors.</p>
<h3><a class="anchor" id="ios_air_step_2"></a>
Step 2: Creating an Xcode project for iPhone</h3>
<p>Create a Single View-based Application project and name it Air. Open the ViewController.xib(main storyboard) file in the Interface Builder.Double-click on the View item and populate it with the views listed below and shown in Figure 3:</p>
<ul>
<li>A Label ("Enter Country")</li>
<li>A Text Field</li>
<li>One Round Rect Button ("Get Airport Information" button)</li>
<li>One Text View (to show the results)</li>
</ul>
<p>In Xcode, edit the file ViewController.h to make it look like the following:</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;@interface ViewController : UIViewController {</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;    UITextField* country_name;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;    UITextView* showResults;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;}</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;@property (strong, nonatomic) IBOutlet UITextField *country_name;</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;@property (strong, nonatomic) IBOutlet UITextView *showResults;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;-(IBAction) buttonPressed;</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;@end</div></div><!-- fragment --><p>Set the <code>country_name</code> and <code>showResults</code> outlets and the <code>buttonFindCountry:(id)sender</code> method to delegate action of the button.</p>
<p>In Xcode, edit the file info.plist to make it look like the following: </p><pre class="fragment">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
&lt;plist version="1.0"&gt;
  &lt;dict&gt;
    &lt;key&gt;NSAppTransportSecurity&lt;/key&gt;
    &lt;dict&gt;
      &lt;key&gt;NSAllowsArbitraryLoads&lt;/key&gt;
      &lt;true/&gt;
    &lt;/dict&gt;
      &lt;key&gt;CFBundleDevelopmentRegion&lt;/key&gt;
      &lt;string&gt;en&lt;/string&gt;
      &lt;key&gt;CFBundleExecutable&lt;/key&gt;
      &lt;string&gt;$(EXECUTABLE_NAME)&lt;/string&gt;
      &lt;key&gt;CFBundleIdentifier&lt;/key&gt;
      &lt;string&gt;$(PRODUCT_BUNDLE_IDENTIFIER)&lt;/string&gt;
      &lt;key&gt;CFBundleInfoDictionaryVersion&lt;/key&gt;
      &lt;string&gt;6.0&lt;/string&gt;
      &lt;key&gt;CFBundleName&lt;/key&gt;
      &lt;string&gt;$(PRODUCT_NAME)&lt;/string&gt;
      &lt;key&gt;CFBundlePackageType&lt;/key&gt;
      &lt;string&gt;APPL&lt;/string&gt;
      &lt;key&gt;CFBundleShortVersionString&lt;/key&gt;
      &lt;string&gt;1.0&lt;/string&gt;
      &lt;key&gt;CFBundleSignature&lt;/key&gt;
      &lt;string&gt;????&lt;/string&gt;
      &lt;key&gt;CFBundleVersion&lt;/key&gt;
      &lt;string&gt;1&lt;/string&gt;
      &lt;key&gt;LSRequiresIPhoneOS&lt;/key&gt;
      &lt;true/&gt;
      &lt;key&gt;UILaunchStoryboardName&lt;/key&gt;
      &lt;string&gt;LaunchScreen&lt;/string&gt;
      &lt;key&gt;UIMainStoryboardFile&lt;/key&gt;
      &lt;string&gt;Main&lt;/string&gt;
      &lt;key&gt;UIRequiredDeviceCapabilities&lt;/key&gt;
      &lt;array&gt;
        &lt;string&gt;armv7&lt;/string&gt;
      &lt;/array&gt;
      &lt;key&gt;UISupportedInterfaceOrientations&lt;/key&gt;
      &lt;array&gt;
        &lt;string&gt;UIInterfaceOrientationPortrait&lt;/string&gt;
        &lt;string&gt;UIInterfaceOrientationLandscapeLeft&lt;/string&gt;
        &lt;string&gt;UIInterfaceOrientationLandscapeRight&lt;/string&gt;
      &lt;/array&gt;
  &lt;/dict&gt;
&lt;/plist&gt;
</pre><p>These changes ensure that you can access the web services despite the added layer of protection of App Transport Security).</p>
<h3><a class="anchor" id="ios_air_step_3"></a>
Step 3: Adding generated source stubs to the Xcode project</h3>
<p>Add the source files soapC.cpp, soapairportSoapProxy.cpp, soapairportSoapProxy.h, soapH.h, and soapStub.h generated in Step 1 of this tutorial to the project. Also add files stdsoap2.h and stdsoap2.cpp to the project from the gSOAP package and the iOS plugin files <a class="el" href="gsoapios_8h.html">gsoapios.h</a> and <a class="el" href="gsoapios_8mm.html">gsoapios.mm</a>.</p>
<p>Once all of your files have been added to the project, ensure they are all of type "Objective C++ Source". This ensures that there will be no issues with mixing Objective C and C++ code.</p>
<h3><a class="anchor" id="ios_air_step_4"></a>
Step 4: Implementing the Logic by calling the soap service</h3>
<p>Firstly, edit file main.mm to import the file airportSoap.nsmap. Linking errors would arise without importing this XML namespace mapping table.</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;// File: main.mm</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &lt;UIKit/UIKit.h&gt;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;#import &quot;AppDelegate.h&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;#include &quot;../../airportSoap.nsmap&quot;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;int main(int argc, char * argv[]) {</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;   @autoreleasepool {</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;     return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;   }</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;}</div></div><!-- fragment --><p>Then, we implement the source file ViewController.mm as the following, where we used the <a href="http://www.genivia.com/doc/dom/html">gSOAP domcpp</a> tool with option -i on an example weather XML data file to produce DOM code to extract the XML data (see further below)</p>
<div class="fragment"><div class="line"><a name="l00001"></a><span class="lineno">    1</span>&#160;#import &quot;ViewController.h&quot;</div><div class="line"><a name="l00002"></a><span class="lineno">    2</span>&#160;#include &quot;soapairportSoapProxy.h&quot;</div><div class="line"><a name="l00003"></a><span class="lineno">    3</span>&#160;#import &quot;soapStub.h&quot;</div><div class="line"><a name="l00004"></a><span class="lineno">    4</span>&#160;#import &quot;gsoapios.h&quot;</div><div class="line"><a name="l00005"></a><span class="lineno">    5</span>&#160;#include &lt;fstream&gt;</div><div class="line"><a name="l00006"></a><span class="lineno">    6</span>&#160;</div><div class="line"><a name="l00007"></a><span class="lineno">    7</span>&#160;@interface ViewController ()</div><div class="line"><a name="l00008"></a><span class="lineno">    8</span>&#160;</div><div class="line"><a name="l00009"></a><span class="lineno">    9</span>&#160;@end</div><div class="line"><a name="l00010"></a><span class="lineno">   10</span>&#160;</div><div class="line"><a name="l00011"></a><span class="lineno">   11</span>&#160;@implementation ViewController</div><div class="line"><a name="l00012"></a><span class="lineno">   12</span>&#160;@synthesize country_name;</div><div class="line"><a name="l00013"></a><span class="lineno">   13</span>&#160;@synthesize showResults;</div><div class="line"><a name="l00014"></a><span class="lineno">   14</span>&#160;</div><div class="line"><a name="l00015"></a><span class="lineno">   15</span>&#160;- (IBAction)buttonPressed:(id)sender {</div><div class="line"><a name="l00016"></a><span class="lineno">   16</span>&#160;  _ns1__GetAirportInformationByCountry sending;</div><div class="line"><a name="l00017"></a><span class="lineno">   17</span>&#160;  _ns1__GetAirportInformationByCountryResponse receiving;</div><div class="line"><a name="l00018"></a><span class="lineno">   18</span>&#160;  std::string result = &quot;&quot;;      //stores resulting data</div><div class="line"><a name="l00019"></a><span class="lineno">   19</span>&#160;  bool webserviceresult = true; //keeps track of if the web service returns a readable result</div><div class="line"><a name="l00020"></a><span class="lineno">   20</span>&#160;</div><div class="line"><a name="l00021"></a><span class="lineno">   21</span>&#160;  airportSoapProxy service;</div><div class="line"><a name="l00022"></a><span class="lineno">   22</span>&#160;  soap_init(service.soap);</div><div class="line"><a name="l00023"></a><span class="lineno">   23</span>&#160;</div><div class="line"><a name="l00024"></a><span class="lineno">   24</span>&#160;  // ----- register plugin for callbacks ------</div><div class="line"><a name="l00025"></a><span class="lineno">   25</span>&#160;  soap_register_plugin(service.soap, soap_ios);</div><div class="line"><a name="l00026"></a><span class="lineno">   26</span>&#160;</div><div class="line"><a name="l00027"></a><span class="lineno">   27</span>&#160;  std::string countryname = std::string((char*)[country_name.text UTF8String]);</div><div class="line"><a name="l00028"></a><span class="lineno">   28</span>&#160;  sending.country = &amp;countryname;</div><div class="line"><a name="l00029"></a><span class="lineno">   29</span>&#160;</div><div class="line"><a name="l00030"></a><span class="lineno">   30</span>&#160;  std::ofstream out(&quot;/Users/bethanysanders/Documents/work/Air/Air/xmlmessage.txt&quot;);</div><div class="line"><a name="l00031"></a><span class="lineno">   31</span>&#160;  std::ifstream in(&quot;/Users/bethanysanders/Documents/work/Air/Air/xmlmessage.txt&quot;);</div><div class="line"><a name="l00032"></a><span class="lineno">   32</span>&#160;</div><div class="line"><a name="l00033"></a><span class="lineno">   33</span>&#160;  if (service.GetAirportInformationByCountry(&amp;sending,receiving) == SOAP_OK)</div><div class="line"><a name="l00034"></a><span class="lineno">   34</span>&#160;    if (out.is_open())</div><div class="line"><a name="l00035"></a><span class="lineno">   35</span>&#160;      out &lt;&lt; *(receiving.GetAirportInformationByCountryResult);</div><div class="line"><a name="l00036"></a><span class="lineno">   36</span>&#160;</div><div class="line"><a name="l00037"></a><span class="lineno">   37</span>&#160;  out.close();</div><div class="line"><a name="l00038"></a><span class="lineno">   38</span>&#160;</div><div class="line"><a name="l00039"></a><span class="lineno">   39</span>&#160;  struct soap *ctx = soap_new1(SOAP_C_UTFSTRING | SOAP_XML_INDENT | SOAP_DOM_TREE);</div><div class="line"><a name="l00040"></a><span class="lineno">   40</span>&#160;  ctx-&gt;double_format = &quot;%lG&quot;;</div><div class="line"><a name="l00041"></a><span class="lineno">   41</span>&#160;</div><div class="line"><a name="l00042"></a><span class="lineno">   42</span>&#160;  xsd__anyType dom(ctx);</div><div class="line"><a name="l00043"></a><span class="lineno">   43</span>&#160;  if (in.is_open())</div><div class="line"><a name="l00044"></a><span class="lineno">   44</span>&#160;    in &gt;&gt; dom;</div><div class="line"><a name="l00045"></a><span class="lineno">   45</span>&#160;  if (dom.soap-&gt;error)</div><div class="line"><a name="l00046"></a><span class="lineno">   46</span>&#160;    webserviceresult = false;</div><div class="line"><a name="l00047"></a><span class="lineno">   47</span>&#160;  xsd__anyType *elt;</div><div class="line"><a name="l00048"></a><span class="lineno">   48</span>&#160;</div><div class="line"><a name="l00049"></a><span class="lineno">   49</span>&#160;  for (xsd__anyType *it = dom.elt_get(&quot;Table&quot;); it; it = it-&gt;get_next())</div><div class="line"><a name="l00050"></a><span class="lineno">   50</span>&#160;  {</div><div class="line"><a name="l00051"></a><span class="lineno">   51</span>&#160;    xsd__anyType&amp; dom_Table = *it;</div><div class="line"><a name="l00052"></a><span class="lineno">   52</span>&#160;    if ((elt = dom_Table.elt_get(&quot;AirportCode&quot;)))</div><div class="line"><a name="l00053"></a><span class="lineno">   53</span>&#160;    {</div><div class="line"><a name="l00054"></a><span class="lineno">   54</span>&#160;      xsd__anyType&amp; dom_Table_AirportCode = *elt;</div><div class="line"><a name="l00055"></a><span class="lineno">   55</span>&#160;      if (dom_Table_AirportCode.get_text())</div><div class="line"><a name="l00056"></a><span class="lineno">   56</span>&#160;      {</div><div class="line"><a name="l00057"></a><span class="lineno">   57</span>&#160;        result += &quot;\n\nAirport Code = &quot;;</div><div class="line"><a name="l00058"></a><span class="lineno">   58</span>&#160;        result += dom_Table_AirportCode.get_text();</div><div class="line"><a name="l00059"></a><span class="lineno">   59</span>&#160;      }</div><div class="line"><a name="l00060"></a><span class="lineno">   60</span>&#160;</div><div class="line"><a name="l00061"></a><span class="lineno">   61</span>&#160;    }</div><div class="line"><a name="l00062"></a><span class="lineno">   62</span>&#160;    if ((elt = dom_Table.elt_get(&quot;CityOrAirportName&quot;)))</div><div class="line"><a name="l00063"></a><span class="lineno">   63</span>&#160;    {</div><div class="line"><a name="l00064"></a><span class="lineno">   64</span>&#160;      xsd__anyType&amp; dom_Table_CityOrAirportName = *elt;</div><div class="line"><a name="l00065"></a><span class="lineno">   65</span>&#160;      if (dom_Table_CityOrAirportName.get_text())</div><div class="line"><a name="l00066"></a><span class="lineno">   66</span>&#160;      {</div><div class="line"><a name="l00067"></a><span class="lineno">   67</span>&#160;        result += &quot;\nCity or Airport Name = &quot;;</div><div class="line"><a name="l00068"></a><span class="lineno">   68</span>&#160;        result += dom_Table_CityOrAirportName.get_text();</div><div class="line"><a name="l00069"></a><span class="lineno">   69</span>&#160;      }</div><div class="line"><a name="l00070"></a><span class="lineno">   70</span>&#160;    }</div><div class="line"><a name="l00071"></a><span class="lineno">   71</span>&#160;    if ((elt = dom_Table.elt_get(&quot;Country&quot;)))</div><div class="line"><a name="l00072"></a><span class="lineno">   72</span>&#160;    {</div><div class="line"><a name="l00073"></a><span class="lineno">   73</span>&#160;      xsd__anyType&amp; dom_Table_Country = *elt;</div><div class="line"><a name="l00074"></a><span class="lineno">   74</span>&#160;      if (dom_Table_Country.get_text())</div><div class="line"><a name="l00075"></a><span class="lineno">   75</span>&#160;      {</div><div class="line"><a name="l00076"></a><span class="lineno">   76</span>&#160;        result += &quot;\nCountry = &quot;;</div><div class="line"><a name="l00077"></a><span class="lineno">   77</span>&#160;        result += dom_Table_Country.get_text();</div><div class="line"><a name="l00078"></a><span class="lineno">   78</span>&#160;      }</div><div class="line"><a name="l00079"></a><span class="lineno">   79</span>&#160;    }</div><div class="line"><a name="l00080"></a><span class="lineno">   80</span>&#160;    if ((elt = dom_Table.elt_get(&quot;CountryAbbrviation&quot;)))</div><div class="line"><a name="l00081"></a><span class="lineno">   81</span>&#160;    {</div><div class="line"><a name="l00082"></a><span class="lineno">   82</span>&#160;      xsd__anyType&amp; dom_Table_CountryAbbrviation = *elt;</div><div class="line"><a name="l00083"></a><span class="lineno">   83</span>&#160;      if (dom_Table_CountryAbbrviation.get_text())</div><div class="line"><a name="l00084"></a><span class="lineno">   84</span>&#160;      {</div><div class="line"><a name="l00085"></a><span class="lineno">   85</span>&#160;        result += &quot;\nCountry Abbreviation = &quot;;</div><div class="line"><a name="l00086"></a><span class="lineno">   86</span>&#160;        result += dom_Table_CountryAbbrviation.get_text();</div><div class="line"><a name="l00087"></a><span class="lineno">   87</span>&#160;      }</div><div class="line"><a name="l00088"></a><span class="lineno">   88</span>&#160;    }</div><div class="line"><a name="l00089"></a><span class="lineno">   89</span>&#160;    if ((elt = dom_Table.elt_get(&quot;CountryCode&quot;)))</div><div class="line"><a name="l00090"></a><span class="lineno">   90</span>&#160;    {</div><div class="line"><a name="l00091"></a><span class="lineno">   91</span>&#160;      xsd__anyType&amp; dom_Table_CountryCode = *elt;</div><div class="line"><a name="l00092"></a><span class="lineno">   92</span>&#160;      if (dom_Table_CountryCode.get_text())</div><div class="line"><a name="l00093"></a><span class="lineno">   93</span>&#160;      {</div><div class="line"><a name="l00094"></a><span class="lineno">   94</span>&#160;        result += &quot;\nCountry Code = &quot;;</div><div class="line"><a name="l00095"></a><span class="lineno">   95</span>&#160;        result += dom_Table_CountryCode.get_text();</div><div class="line"><a name="l00096"></a><span class="lineno">   96</span>&#160;      }</div><div class="line"><a name="l00097"></a><span class="lineno">   97</span>&#160;    }</div><div class="line"><a name="l00098"></a><span class="lineno">   98</span>&#160;    if ((elt = dom_Table.elt_get(&quot;GMTOffset&quot;)))</div><div class="line"><a name="l00099"></a><span class="lineno">   99</span>&#160;    {</div><div class="line"><a name="l00100"></a><span class="lineno">  100</span>&#160;      xsd__anyType&amp; dom_Table_GMTOffset = *elt;</div><div class="line"><a name="l00101"></a><span class="lineno">  101</span>&#160;      if (dom_Table_GMTOffset.get_text())</div><div class="line"><a name="l00102"></a><span class="lineno">  102</span>&#160;      {</div><div class="line"><a name="l00103"></a><span class="lineno">  103</span>&#160;        result += &quot;\nGMT Offset = &quot;;</div><div class="line"><a name="l00104"></a><span class="lineno">  104</span>&#160;        result += dom_Table_GMTOffset.get_text();</div><div class="line"><a name="l00105"></a><span class="lineno">  105</span>&#160;      }</div><div class="line"><a name="l00106"></a><span class="lineno">  106</span>&#160;    }</div><div class="line"><a name="l00107"></a><span class="lineno">  107</span>&#160;    if ((elt = dom_Table.elt_get(&quot;RunwayLengthFeet&quot;)))</div><div class="line"><a name="l00108"></a><span class="lineno">  108</span>&#160;    {</div><div class="line"><a name="l00109"></a><span class="lineno">  109</span>&#160;      xsd__anyType&amp; dom_Table_RunwayLengthFeet = *elt;</div><div class="line"><a name="l00110"></a><span class="lineno">  110</span>&#160;      if (dom_Table_RunwayLengthFeet.get_text())</div><div class="line"><a name="l00111"></a><span class="lineno">  111</span>&#160;      {</div><div class="line"><a name="l00112"></a><span class="lineno">  112</span>&#160;        result += &quot;\nRunway Length (feet) = &quot;;</div><div class="line"><a name="l00113"></a><span class="lineno">  113</span>&#160;        result += dom_Table_RunwayLengthFeet.get_text();</div><div class="line"><a name="l00114"></a><span class="lineno">  114</span>&#160;      }</div><div class="line"><a name="l00115"></a><span class="lineno">  115</span>&#160;    }</div><div class="line"><a name="l00116"></a><span class="lineno">  116</span>&#160;    if ((elt = dom_Table.elt_get(&quot;RunwayElevationFeet&quot;)))</div><div class="line"><a name="l00117"></a><span class="lineno">  117</span>&#160;    {</div><div class="line"><a name="l00118"></a><span class="lineno">  118</span>&#160;      xsd__anyType&amp; dom_Table_RunwayElevationFeet = *elt;</div><div class="line"><a name="l00119"></a><span class="lineno">  119</span>&#160;      if (dom_Table_RunwayElevationFeet.get_text())</div><div class="line"><a name="l00120"></a><span class="lineno">  120</span>&#160;      {</div><div class="line"><a name="l00121"></a><span class="lineno">  121</span>&#160;        result += &quot;\nRunway Elevation (feet) = &quot;;</div><div class="line"><a name="l00122"></a><span class="lineno">  122</span>&#160;        result += dom_Table_RunwayElevationFeet.get_text();</div><div class="line"><a name="l00123"></a><span class="lineno">  123</span>&#160;      }</div><div class="line"><a name="l00124"></a><span class="lineno">  124</span>&#160;    }</div><div class="line"><a name="l00125"></a><span class="lineno">  125</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LatitudeDegree&quot;)))</div><div class="line"><a name="l00126"></a><span class="lineno">  126</span>&#160;    {</div><div class="line"><a name="l00127"></a><span class="lineno">  127</span>&#160;      xsd__anyType&amp; dom_Table_LatitudeDegree = *elt;</div><div class="line"><a name="l00128"></a><span class="lineno">  128</span>&#160;      if (dom_Table_LatitudeDegree.get_text())</div><div class="line"><a name="l00129"></a><span class="lineno">  129</span>&#160;      {</div><div class="line"><a name="l00130"></a><span class="lineno">  130</span>&#160;        result += &quot;\nLatitude Degree = &quot;;</div><div class="line"><a name="l00131"></a><span class="lineno">  131</span>&#160;        result += dom_Table_LatitudeDegree.get_text();</div><div class="line"><a name="l00132"></a><span class="lineno">  132</span>&#160;      }</div><div class="line"><a name="l00133"></a><span class="lineno">  133</span>&#160;    }</div><div class="line"><a name="l00134"></a><span class="lineno">  134</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LatitudeMinute&quot;)))</div><div class="line"><a name="l00135"></a><span class="lineno">  135</span>&#160;    {</div><div class="line"><a name="l00136"></a><span class="lineno">  136</span>&#160;      xsd__anyType&amp; dom_Table_LatitudeMinute = *elt;</div><div class="line"><a name="l00137"></a><span class="lineno">  137</span>&#160;      if (dom_Table_LatitudeMinute.get_text())</div><div class="line"><a name="l00138"></a><span class="lineno">  138</span>&#160;      {</div><div class="line"><a name="l00139"></a><span class="lineno">  139</span>&#160;        result += &quot;\nLatitude Minute = &quot;;</div><div class="line"><a name="l00140"></a><span class="lineno">  140</span>&#160;        result += dom_Table_LatitudeMinute.get_text();</div><div class="line"><a name="l00141"></a><span class="lineno">  141</span>&#160;      }</div><div class="line"><a name="l00142"></a><span class="lineno">  142</span>&#160;    }</div><div class="line"><a name="l00143"></a><span class="lineno">  143</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LatitudeSecond&quot;)))</div><div class="line"><a name="l00144"></a><span class="lineno">  144</span>&#160;    {</div><div class="line"><a name="l00145"></a><span class="lineno">  145</span>&#160;      xsd__anyType&amp; dom_Table_LatitudeSecond = *elt;</div><div class="line"><a name="l00146"></a><span class="lineno">  146</span>&#160;      if (dom_Table_LatitudeSecond.get_text())</div><div class="line"><a name="l00147"></a><span class="lineno">  147</span>&#160;      {</div><div class="line"><a name="l00148"></a><span class="lineno">  148</span>&#160;        result += &quot;\nLatitude Second = &quot;;</div><div class="line"><a name="l00149"></a><span class="lineno">  149</span>&#160;        result += dom_Table_LatitudeSecond.get_text();</div><div class="line"><a name="l00150"></a><span class="lineno">  150</span>&#160;      }</div><div class="line"><a name="l00151"></a><span class="lineno">  151</span>&#160;    }</div><div class="line"><a name="l00152"></a><span class="lineno">  152</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LatitudeNpeerS&quot;)))</div><div class="line"><a name="l00153"></a><span class="lineno">  153</span>&#160;    {</div><div class="line"><a name="l00154"></a><span class="lineno">  154</span>&#160;      xsd__anyType&amp; dom_Table_LatitudeNpeerS = *elt;</div><div class="line"><a name="l00155"></a><span class="lineno">  155</span>&#160;      if (dom_Table_LatitudeNpeerS.get_text())</div><div class="line"><a name="l00156"></a><span class="lineno">  156</span>&#160;      {</div><div class="line"><a name="l00157"></a><span class="lineno">  157</span>&#160;        result += &quot;\nLatitude N or S = &quot;;</div><div class="line"><a name="l00158"></a><span class="lineno">  158</span>&#160;        result += dom_Table_LatitudeNpeerS.get_text();</div><div class="line"><a name="l00159"></a><span class="lineno">  159</span>&#160;      }</div><div class="line"><a name="l00160"></a><span class="lineno">  160</span>&#160;    }</div><div class="line"><a name="l00161"></a><span class="lineno">  161</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LongitudeDegree&quot;)))</div><div class="line"><a name="l00162"></a><span class="lineno">  162</span>&#160;    {</div><div class="line"><a name="l00163"></a><span class="lineno">  163</span>&#160;      xsd__anyType&amp; dom_Table_LongitudeDegree = *elt;</div><div class="line"><a name="l00164"></a><span class="lineno">  164</span>&#160;      if (dom_Table_LongitudeDegree.get_text())</div><div class="line"><a name="l00165"></a><span class="lineno">  165</span>&#160;      {</div><div class="line"><a name="l00166"></a><span class="lineno">  166</span>&#160;        result += &quot;\nLongitude Degree = &quot;;</div><div class="line"><a name="l00167"></a><span class="lineno">  167</span>&#160;        result += dom_Table_LongitudeDegree.get_text();</div><div class="line"><a name="l00168"></a><span class="lineno">  168</span>&#160;      }</div><div class="line"><a name="l00169"></a><span class="lineno">  169</span>&#160;    }</div><div class="line"><a name="l00170"></a><span class="lineno">  170</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LongitudeMinute&quot;)))</div><div class="line"><a name="l00171"></a><span class="lineno">  171</span>&#160;    {</div><div class="line"><a name="l00172"></a><span class="lineno">  172</span>&#160;      xsd__anyType&amp; dom_Table_LongitudeMinute = *elt;</div><div class="line"><a name="l00173"></a><span class="lineno">  173</span>&#160;      if (dom_Table_LongitudeMinute.get_text())</div><div class="line"><a name="l00174"></a><span class="lineno">  174</span>&#160;      {</div><div class="line"><a name="l00175"></a><span class="lineno">  175</span>&#160;        result += &quot;\nLongitude Minute = &quot;;</div><div class="line"><a name="l00176"></a><span class="lineno">  176</span>&#160;        result += dom_Table_LongitudeMinute.get_text();</div><div class="line"><a name="l00177"></a><span class="lineno">  177</span>&#160;      }</div><div class="line"><a name="l00178"></a><span class="lineno">  178</span>&#160;    }</div><div class="line"><a name="l00179"></a><span class="lineno">  179</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LongitudeSeconds&quot;)))</div><div class="line"><a name="l00180"></a><span class="lineno">  180</span>&#160;    {</div><div class="line"><a name="l00181"></a><span class="lineno">  181</span>&#160;      xsd__anyType&amp; dom_Table_LongitudeSeconds = *elt;</div><div class="line"><a name="l00182"></a><span class="lineno">  182</span>&#160;      if (dom_Table_LongitudeSeconds.get_text())</div><div class="line"><a name="l00183"></a><span class="lineno">  183</span>&#160;      {</div><div class="line"><a name="l00184"></a><span class="lineno">  184</span>&#160;        result += &quot;\nLongitude Second = &quot;;</div><div class="line"><a name="l00185"></a><span class="lineno">  185</span>&#160;        result += dom_Table_LongitudeSeconds.get_text();</div><div class="line"><a name="l00186"></a><span class="lineno">  186</span>&#160;      }</div><div class="line"><a name="l00187"></a><span class="lineno">  187</span>&#160;    }</div><div class="line"><a name="l00188"></a><span class="lineno">  188</span>&#160;    if ((elt = dom_Table.elt_get(&quot;LongitudeEperW&quot;)))</div><div class="line"><a name="l00189"></a><span class="lineno">  189</span>&#160;    {</div><div class="line"><a name="l00190"></a><span class="lineno">  190</span>&#160;      xsd__anyType&amp; dom_Table_LongitudeEperW = *elt;</div><div class="line"><a name="l00191"></a><span class="lineno">  191</span>&#160;      if (dom_Table_LongitudeEperW.get_text())</div><div class="line"><a name="l00192"></a><span class="lineno">  192</span>&#160;      {</div><div class="line"><a name="l00193"></a><span class="lineno">  193</span>&#160;        result += &quot;\nLongitude E or W = &quot;;</div><div class="line"><a name="l00194"></a><span class="lineno">  194</span>&#160;        result += dom_Table_LongitudeEperW.get_text();</div><div class="line"><a name="l00195"></a><span class="lineno">  195</span>&#160;      }</div><div class="line"><a name="l00196"></a><span class="lineno">  196</span>&#160;    }</div><div class="line"><a name="l00197"></a><span class="lineno">  197</span>&#160;  }</div><div class="line"><a name="l00198"></a><span class="lineno">  198</span>&#160;</div><div class="line"><a name="l00199"></a><span class="lineno">  199</span>&#160;  NSString *airPorts = [NSString stringWithUTF8String:result.c_str()];</div><div class="line"><a name="l00200"></a><span class="lineno">  200</span>&#160;  if (result == &quot;&quot; || !webserviceresult)</div><div class="line"><a name="l00201"></a><span class="lineno">  201</span>&#160;    airPorts = [NSString stringWithFormat: @&quot;%@&quot;, @&quot;Error: no know information. Try a different country.&quot;];</div><div class="line"><a name="l00202"></a><span class="lineno">  202</span>&#160;</div><div class="line"><a name="l00203"></a><span class="lineno">  203</span>&#160;  showResults.editable = NO;</div><div class="line"><a name="l00204"></a><span class="lineno">  204</span>&#160;  showResults.showsVerticalScrollIndicator = YES;</div><div class="line"><a name="l00205"></a><span class="lineno">  205</span>&#160;  showResults.text = airPorts;</div><div class="line"><a name="l00206"></a><span class="lineno">  206</span>&#160;</div><div class="line"><a name="l00207"></a><span class="lineno">  207</span>&#160;  soap_destroy(ctx); // delete objects</div><div class="line"><a name="l00208"></a><span class="lineno">  208</span>&#160;  soap_end(ctx);     // delete DOM data</div><div class="line"><a name="l00209"></a><span class="lineno">  209</span>&#160;  soap_free(ctx);    // free context</div><div class="line"><a name="l00210"></a><span class="lineno">  210</span>&#160;</div><div class="line"><a name="l00211"></a><span class="lineno">  211</span>&#160;  service.destroy();</div><div class="line"><a name="l00212"></a><span class="lineno">  212</span>&#160;}</div><div class="line"><a name="l00213"></a><span class="lineno">  213</span>&#160;</div><div class="line"><a name="l00214"></a><span class="lineno">  214</span>&#160;- (void)viewDidLoad {</div><div class="line"><a name="l00215"></a><span class="lineno">  215</span>&#160;    [super viewDidLoad];</div><div class="line"><a name="l00216"></a><span class="lineno">  216</span>&#160;    // Do any additional setup after loading the view, typically from a nib.</div><div class="line"><a name="l00217"></a><span class="lineno">  217</span>&#160;}</div><div class="line"><a name="l00218"></a><span class="lineno">  218</span>&#160;</div><div class="line"><a name="l00219"></a><span class="lineno">  219</span>&#160;- (void)didReceiveMemoryWarning {</div><div class="line"><a name="l00220"></a><span class="lineno">  220</span>&#160;    [super didReceiveMemoryWarning];</div><div class="line"><a name="l00221"></a><span class="lineno">  221</span>&#160;    // Dispose of any resources that can be recreated.</div><div class="line"><a name="l00222"></a><span class="lineno">  222</span>&#160;}</div><div class="line"><a name="l00223"></a><span class="lineno">  223</span>&#160;@end</div></div><!-- fragment --><p>You will notice there is much more code in this example's ViewController.mm. This is because this web service stores the whole XML response within a string instead of appropriate variables. The dom parser can fix this situation so that you can still access your results without having to parse the XML yourself. The dom code in this example was generated via command line in UNIX. To do so, once you have dom executable in your working directory, just execute the command </p><pre class="fragment">./domcpp -i airPorts.xml
</pre><p>where airPorts.xml is a file that stores an example xml response. The option -i is what tells the dom tool to generate the code you need to parse your result. To obtain an example XML response, test the web service on <a href="http://www.webservicex.net/New/Home/ServiceDetail/20">http://www.webservicex.net/New/Home/ServiceDetail/20</a>.</p>
<p>The domcpp tool is found in gsoap/samples/dom and should be built in that directory with: </p><pre class="fragment">make domcpp
</pre><p>Then move or copy the domcpp executable to use it for your projects.</p>
<p>For more information about domcpp, read <a href="https://www.genivia.com/doc/dom/html/index.html">XML DOM and XPath</a> of the gSOAP documentation. </p>
</div></div><!-- contents -->
<hr class="footer">
<address class="footer">
Copyright (C) 2020, Robert van Engelen, Genivia Inc., All Rights Reserved.
</address>
<address class="footer"><small>
Converted on Wed Apr 8 2020 09:28:59 by <a target="_blank" href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.11</small></address>
<br>
<div style="height: 246px; background: #DBDBDB;">
</body>
</html>
